﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Metadata.Edm;
using System.Data.Objects;
using System.Linq;
using System.Text;
using Arch.Data;
using Microsoft.Practices.Unity;

namespace Arch.EF.Data
{
    public class DbRepository<T> : ArchRepository<T> where T : class, new()
    {
        [Dependency]
        public virtual DbContext Context { get; set; }

        public string DefaultIncludes { get; set; }

        private DbSet<T> _set;
        public DbSet<T> Set
        {
            get { return _set ?? (_set = Context.Set<T>()); }
        }

        public override IQueryable<T> GetQuery()
        {
            DbQuery<T> q = Set;
            if (DefaultIncludes != null)
            {
                q = (DefaultIncludes).Split(',').Aggregate(q, (current, include) => 
                    current.Include(include.Trim()));
            }
            return q;
        }

        public override T Load(object id)
        {
            return Set.Find(id);
        }

        public override T Create(T entity)
        {
            return Set.Add(entity);
        }

        public override T Delete(T entity)
        {
            return Set.Remove(entity);
        }

        public override T Update(T entity)
        {
            return entity;
        }

        public override T New()
        {
            return Set.Create();
        }

        public override T Attach(T entity, bool modified = false)
        {
            Set.Attach(entity);
            if (modified)
            {
                Context.Entry(entity).State = EntityState.Modified;
            }
            return entity;
        }

        public override T Detach(T entity)
        {
            Context.Entry(entity).State = EntityState.Detached;
            return entity;
        }
    }

    public class DbRepository : ArchRepository
    {
        [Dependency]
        public DbContext Context { get; set; }

        public override void SaveChanges()
        {
            Context.SaveChanges();
        }
    }
}
